#ifndef SINGLETONE_H
#define SINGLETONE_H

#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>

namespace network {
	template <class T>
	class singletone : public boost::noncopyable {
	private:
		static boost::mutex _monitor;
		static boost::shared_ptr<boost::mutex> _mon;
		static boost::shared_ptr<T> _obj;
	public:

		static boost::shared_ptr<boost::mutex> get_monitor() 
		{
			if(_mon.get() == 0) {
				boost::mutex::scoped_lock l(_monitor);
				if(_mon.get() == 0) {
					_mon.reset(new boost::mutex());
				}
			}
			return _mon;
		}

		static boost::shared_ptr<T> instance() 
		{
			if(_mon.get() == 0) {
				boost::mutex::scoped_lock l2(_monitor);
				if(_mon.get() == 0) {
					_mon.reset(new boost::mutex());
				}
			}
			if(_obj.get() == 0) {
				boost::mutex::scoped_lock l(*_mon);
				if(_obj.get() == 0) {
					_obj.reset(new T);
				}
			}
			return _obj;
		}
	private:
		singletone() {}
	};

	template <class T>
	boost::mutex network::singletone<T>::_monitor;
	template <class T>
	boost::shared_ptr<boost::mutex> network::singletone<T>::_mon;
	template <class T>
	boost::shared_ptr<T> network::singletone<T>::_obj;
}

#endif
